//     Zepto.js
//     (c) 2010-2016 Thomas Fuchs
//     Zepto.js may be freely distributed under the MIT license.

;
(function($) {
    var zepto = $.zepto,
        oldQsa = zepto.qsa,
        oldMatches = zepto.matches

    function visible(elem) {
        elem = $(elem)
        return !!(elem.width() || elem.height()) && elem.css("display") !== "none"
    }

    // Implements a subset from:
    // http://api.jquery.com/category/selectors/jquery-selector-extensions/
    //
    // Each filter function receives the current index, all nodes in the
    // considered set, and a value if there were parentheses. The value
    // of `this` is the node currently being considered. The function returns the
    // resulting node(s), null, or undefined.
    //
    // Complex selectors are not supported:
    //   li:has(label:contains("foo")) + li:has(label:contains("bar"))
    //   ul.inner:first > li
    var filters = $.expr[':'] = {
        visible: function() { if (visible(this)) return this },
        hidden: function() { if (!visible(this)) return this },
        selected: function() { if (this.selected) return this },
        checked: function() { if (this.checked) return this },
        parent: function() { return this.parentNode },
        first: function(idx) { if (idx === 0) return this },
        last: function(idx, nodes) { if (idx === nodes.length - 1) return this },
        eq: function(idx, _, value) { if (idx === value) return this },
        contains: function(idx, _, text) { if ($(this).text().indexOf(text) > -1) return this },
        has: function(idx, _, sel) { if (zepto.qsa(this, sel).length) return this }
    }

    var filterRe = new RegExp('(.*):(\\w+)(?:\\(([^)]+)\\))?$\\s*'),
        childRe = /^\s*>/,
        classTag = 'Zepto' + (+new Date())

    function process(sel, fn) {
        // quote the hash in `a[href^=#]` expression
        sel = sel.replace(/=#\]/g, '="#"]')
        var filter, arg, match = filterRe.exec(sel)
        if (match && match[2] in filters) {
            filter = filters[match[2]], arg = match[3]
            sel = match[1]
            if (arg) {
                var num = Number(arg)
                if (isNaN(num)) arg = arg.replace(/^["']|["']$/g, '')
                else arg = num
            }
        }
        return fn(sel, filter, arg)
    }

    zepto.qsa = function(node, selector) {
        return process(selector, function(sel, filter, arg) {
            try {
                var taggedParent
                if (!sel && filter) sel = '*'
                else if (childRe.test(sel))
                // support "> *" child queries by tagging the parent node with a
                // unique class and prepending that classname onto the selector
                    taggedParent = $(node).addClass(classTag), sel = '.' + classTag + ' ' + sel

                var nodes = oldQsa(node, sel)
            } catch (e) {
                console.error('error performing selector: %o', selector)
                throw e
            } finally {
                if (taggedParent) taggedParent.removeClass(classTag)
            }
            return !filter ? nodes :
                zepto.uniq($.map(nodes, function(n, i) { return filter.call(n, i, nodes, arg) }))
        })
    }

    zepto.matches = function(node, selector) {
        return process(selector, function(sel, filter, arg) {
            return (!sel || oldMatches(node, sel)) &&
                (!filter || filter.call(node, null, arg) === node)
        })
    }
})(Zepto)